#include "openmove_Prefix.h"
#include "SceneBase.h"
#include "OgreEngine.h"
#include "ExampleFrameListener.h"
#include "SkeletalAnimationFrameListener.h"
#include "OgreExternalTextureSourceManager.h"
#include "OgreExternalTextureSource.h"
#include "SceneLoupVoyeur.h"

CSceneLoupVoyeur :: CSceneLoupVoyeur(COgreEngine &Creator, const String & Name, const int pos) : CSceneBase(Creator, Name, pos), m_pRightHand(NULL), m_pRightHandProjector(NULL), m_pRightForeArm(NULL), m_pRightForeArmProjector(NULL), m_pHips(NULL), m_pHipsProjector(NULL)
{
}

CSceneLoupVoyeur :: ~CSceneLoupVoyeur(void)
{
}

void CSceneLoupVoyeur :: Create(TCreatorEntities const &CreatorEntities, TCreatorNodes const &CreatorNodes, TCreatorLights const &CreatorLights, ENetConfig IsClient, Vector3 &CameraStartPos)
{
	CSceneBase::Create(CreatorEntities, CreatorNodes, CreatorLights, IsClient, CameraStartPos);

	Entity *pLoup = findEntity(String("loup-voyeur_nco"));
	if (NULL != pLoup)
	{
		AnimationState *pAnimationState = pLoup->getAnimationState("danse");
		SkeletonInstance *pSkeleton = pLoup->getSkeleton();
		m_pRightHand = pSkeleton->getBone("NCO_RightHand");
		m_pRightForeArm = pSkeleton->getBone("NCO_RightForeArm");
		m_pHips = pSkeleton->getBone("NCO_Hips");

		TexturePtr pTex = TextureManager::getSingleton().load("decal_filter.png", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_1D, 1); 

		MaterialPtr mat = (MaterialPtr)MaterialManager::getSingleton().getByName("loup-voyeur/lambert1");
		Pass *pass = mat->getTechnique(0)->getPass(0);
		TextureUnitState *texState;
		TextureUnitState *pTexState;

		SProjectorFrustum DecalFrustum = CreateProjector("LPDecalProjectorNode", m_pHips->getPosition(), m_pHips->getOrientation());
		SProjectorFrustum RightHandFrustum = CreateProjector("LPRightHandProjector", m_pRightHand->getPosition(), m_pRightHand->getOrientation());
		SProjectorFrustum RightForeArmFrustum = CreateProjector("LPRightForeArmProjector", m_pRightForeArm->getPosition(), m_pRightForeArm->getOrientation());

		SProjectorFrustum MainFrustum = CreateProjector("LPMainProjectorNode", Vector3(-937.442, -10.934, 1546.852), Quaternion(Degree(-23.752), Vector3::UNIT_Y));

		MainFrustum.m_Decal->setFOVy(Radian(Math::PI/4));
		DecalFrustum.m_Decal->setFOVy(Radian(Math::PI/1.75));
		RightHandFrustum.m_Decal->setFOVy(Radian(Math::PI/16));
		RightForeArmFrustum.m_Decal->setFOVy(Radian(Math::PI/32));

		pass->setAmbient(1.0, 1.0, 1.0);
		pass->setSceneBlending(SBT_REPLACE);
		
		texState = pass->createTextureUnitState("plante__spot_video");
		texState->setProjectiveTexturing(true, DecalFrustum.m_Decal);
		texState->setTextureAddressingMode(TextureUnitState::TAM_BORDER);
		texState->setTextureFiltering(TFO_ANISOTROPIC);
		texState->setColourOperation(LBO_REPLACE);
		texState->setTextureBorderColour(ColourValue(0.0f, 0.0f, 0.0f, 0.0f));

		pTexState = pass->createTextureUnitState("decal_filter.png"); 
		pTexState->setProjectiveTexturing(true,DecalFrustum.m_Filter); 
		pTexState->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); 
		pTexState->setTextureFiltering(TFO_NONE); 
		pTexState->setColourOperation(LBO_ALPHA_BLEND);

		texState = pass->createTextureUnitState("spot.tga");
		texState->setProjectiveTexturing(true, RightHandFrustum.m_Decal);
		texState->setTextureAddressingMode(TextureUnitState::TAM_BORDER);
		texState->setTextureFiltering(TFO_ANISOTROPIC);
		texState->setColourOperation(LBO_ALPHA_BLEND);
		texState->setTextureBorderColour(ColourValue(0.0f, 0.0f, 0.0f, 0.0f));

		texState = pass->createTextureUnitState("spot.tga");
		texState->setProjectiveTexturing(true, RightForeArmFrustum.m_Decal);
		texState->setTextureAddressingMode(TextureUnitState::TAM_BORDER);
		texState->setTextureFiltering(TFO_ANISOTROPIC);
		texState->setColourOperation(LBO_ALPHA_BLEND);
		texState->setTextureBorderColour(ColourValue(0.0f, 0.0f, 0.0f, 0.0f));

		pass = mat->getTechnique(0)->createPass();
		pass->setSceneBlending(SBT_ADD);
		pass->setLightingEnabled(true);
		pass->setAmbient(0, 0, 0);
		pass->setDiffuse(1, 1, 1, 1.0);
		pass->setSpecular(0.5, 0.5, 0.5, 1.0);
		pass->setShadingMode(SO_GOURAUD);

		texState = pass->createTextureUnitState("plante__spot_video");
		texState->setProjectiveTexturing(true, MainFrustum.m_Decal);
		texState->setTextureAddressingMode(TextureUnitState::TAM_BORDER);
		texState->setTextureFiltering(TFO_ANISOTROPIC);
		texState->setColourOperationEx(LBX_MODULATE_X2);
		texState->setTextureBorderColour(ColourValue(0.0f, 0.0f, 0.0f, 0.0f));

		SceneNode *node = NULL;
		if (!m_ShowEntitiesBBox)
		{
			node = m_OgreEngine.m_pCurrentSceneManager->getRootSceneNode();
		}
		else
		{
			node = m_pSceneNode;
		}
		m_pRightHandProjector = static_cast<SceneNode *>(node->getChild("LPRightHandProjector"));
		m_pRightForeArmProjector = static_cast<SceneNode *>(node->getChild("LPRightForeArmProjector"));
		m_pHipsProjector = static_cast<SceneNode *>(node->getChild("LPDecalProjectorNode"));
	}

}

void CSceneLoupVoyeur :: Attach(void)
{
	CSceneBase::Attach();
	//m_pCurrentCamera->setPosition(-268.204f, 237.066f, 644.131f);
	//m_pCurrentCamera->setDirection(0, 0, -1);

	//m_OgreEngine.m_pViewPort->setBackgroundColour(ColourValue(0.0f, 0.0f, 0.0f, 1.0f));
}

bool CSceneLoupVoyeur :: frameStarted(const FrameEvent& evt)
{	
	CSceneBase::frameStarted(evt);


	m_pRightHandProjector->setPosition(m_pRightHand->getWorldPosition());
	m_pRightHandProjector->setOrientation(m_pRightHand->getWorldOrientation() *
		Quaternion(Degree(162), Vector3::UNIT_X) *
		Quaternion(Degree(151.6), -Vector3::UNIT_Y) *
		Quaternion(Degree(341), Vector3::UNIT_Z));

	m_pRightForeArmProjector->setPosition(m_pRightForeArm->getWorldPosition());
	m_pRightForeArmProjector->setOrientation(m_pRightForeArm->getWorldOrientation() *
		Quaternion(Degree(-3), Vector3::UNIT_X) *
		Quaternion(Degree(-23), -Vector3::UNIT_Y) *
		Quaternion(Degree(160), Vector3::UNIT_Z));

	m_pHipsProjector->setPosition(m_pHips->getWorldPosition());
	m_pHipsProjector->setOrientation(m_pHips->getWorldOrientation() *
		Quaternion(Degree(-178), Vector3::UNIT_X) *
		Quaternion(Degree(-6), -Vector3::UNIT_Y) *
		Quaternion(Degree(5.5), Vector3::UNIT_Z));

	return (true);
}